#include "aky_com_include.h"


QUEUE_HandleTypeDef  q_simul_rx;
static idata e_simul_tx_stat_t g_e_simul_tx_stat = TX_IDLE;

uint8_t simul_rx_buf[SIMUL_MAX_RX_SIZE];
uint8_t g_u8_send_dat;
volatile uint8_t g_flag_send;

void it_simula_uart_rx_pro(void);
void it_simula_uart_tx_pro(void);
uint8_t IP0_last = 0; //记住上次的优先级设定
uint8_t IP1_last = 0;


#define TC0_RELOAD_VAL 0XFFFF - 12  //(32000000 / 128) * 0.000052 = 13  52US

//模拟串口引脚初始化
void it_simula_uart_io_init(void)
{
    SIMUL_RX_PROT_REG &= ~SIMUL_RX_PIN; // IO端口方向
    SIMUL_RX_UP_REG |= SIMUL_RX_PIN;    // 上拉配置

    SIMUL_TX_PROT_REG |= SIMUL_TX_PIN; // IO端口方向
    SIMUL_TX_UP_REG &= ~SIMUL_TX_PIN;  // 上拉配置
    SIMUL_TX_H;
}

//初始化 打开一个52us的定时器中断
void it_simula_uart_init(void)
{
    TC0M = 0X00; // TC0 Clock = fcpu/128
    TC0C = TC0_RELOAD_VAL;//TC0 COUNTING Register
    TC0R = TC0_RELOAD_VAL;//AUTO-Reload Register
    IEN2 |= 0x02; // TC0IEN = 1
    TC0M |= 0X80; // TC0ENB = 1
    IEN0 |= 0x80; // EAL = 1
    IP0_last = IP0; //记住上次的优先级设定
    IP1_last = IP1;
	IP0 = 0x00;			//
	IP1 = 0x00;
	IP0 |= (1 << 2);//tc0设置最高优先级
	IP1 |= (1 << 2);

    it_simula_uart_io_init();

    Queue_Init(&q_simul_rx, &simul_rx_buf[0], SIMUL_MAX_RX_SIZE);
    Queue_Clear(&q_simul_rx);
}

//注销处理
void it_simula_uart_deinit(void)
{
    IP0 = IP0_last; //恢复上次记住的优先级设定
    IP1 = IP1_last;
    TC0M = 0X00; // 关闭tc0
    IEN2 &= ~0x02; // TC0IEN = 0 关闭中断
}

//发送和接收处理
//52us定时器中调用
void it_simula_uart_pro(void)
{
    it_simula_uart_rx_pro();
    it_simula_uart_tx_pro();
}

//取当前rx接收状态
//return 1 当前接收到1帧数据  \0 没有接收到数据
uint8_t get_simul_uart_rx_stat(void)
{
    uint8_t res = 0;
    if (Queue_Count(&q_simul_rx))
    {
        res = 1;
    }
    return res;
}

//取当前tx发送状态
//return 1 当前已发送完成1帧数据  \0 正在发送中
uint8_t get_simul_uart_tx_stat(void)
{
    uint8_t res = 0;
    if (g_flag_send == 0)
    {
        res = 1;
    }
    return res;
}

//发送一字节数据
void it_simula_uart_send_byte(unsigned char dat)
{
    volatile uint16_t sendcount = 0;

    g_u8_send_dat = dat;
    g_flag_send = 1;
    while (get_simul_uart_tx_stat() == 0)//等待发送完成
    {
        sendcount++;
        if (sendcount > 2000)
        {
            break;
        }
    }
    g_flag_send = 0;
}


//返回接受到的一字节数据
unsigned char it_simula_uart_get_byte(void)
{
    uint8_t res = 0;
    Queue_Pop(&q_simul_rx, &res);
    return res;
}

//中断发送处理
void it_simula_uart_tx_pro(void)
{
    static idata uint16_t tx_tick_cnt = 0;
    static idata uint8_t tx_temp = 0;
    static idata uint8_t tx_mask_cnt = 0;
    switch (g_e_simul_tx_stat)
    {
    case TX_IDLE:
        {
            SIMUL_TX_H;
            if (g_flag_send == 1)
            {
                tx_temp = 0;
                tx_mask_cnt = 0;
                tx_tick_cnt = 0;
                tx_temp = g_u8_send_dat;
                g_e_simul_tx_stat = TX_START_BIT;
            }
        }
        break;
    case TX_START_BIT:
        {
            SIMUL_TX_L;
            tx_tick_cnt++;
            if (tx_tick_cnt >= SIMUL_UART_ONE_TICK)
            {
                tx_tick_cnt = 0xff;
                g_e_simul_tx_stat = TX_SEND_8_BIT_DAT;
            }
        }
        break;
    case TX_SEND_8_BIT_DAT:
        {
            tx_tick_cnt++;
            if (tx_tick_cnt >= SIMUL_UART_ONE_TICK)
            {
                tx_tick_cnt = 0;
                if (tx_temp & 0x01)
                {
                    SIMUL_TX_H;
                }
                else
                {
                    SIMUL_TX_L;
                }
                tx_temp>>= 1;
                tx_mask_cnt++;
                if (tx_mask_cnt >= 8)
                {
                    tx_mask_cnt = 0;
                    g_e_simul_tx_stat = TX_SEND_END_BIT;
                }
            }
        }
        break;
    case TX_SEND_END_BIT:
        {
            tx_tick_cnt++;
            if (tx_tick_cnt >= SIMUL_UART_ONE_TICK)
            {
                tx_tick_cnt = 0;
                SIMUL_TX_H;
                g_flag_send = 0;
                g_e_simul_tx_stat = TX_SEND_1BYTE_SUCC;
            }
        }
        break;
    case TX_SEND_1BYTE_SUCC:
        {
            tx_tick_cnt++;
            if (tx_tick_cnt >= (SIMUL_UART_ONE_TICK * 2))
            {
                tx_tick_cnt = 0;
                g_e_simul_tx_stat = TX_IDLE;
            }
        }
        break;
    case TX_SEND_ERR:
        {
            g_e_simul_tx_stat = TX_IDLE;
        }
        break;

    default:
        g_e_simul_tx_stat = TX_IDLE;
        break;
    }
}

idata e_simul_rx_stat_t  g_e_simul_rx_stat = RX_IDLE;
//中断接收处理
void it_simula_uart_rx_pro(void)
{
    static idata uint16_t rx_tick_cnt = 0;
    static idata uint16_t rx_time_out_cnt = 0;
    static idata uint8_t rx_temp = 0;
    static idata uint8_t rx_mask_cnt = 0;
    static idata uint8_t last_pin_stat = 0;

    switch (g_e_simul_rx_stat)
    {
    case RX_IDLE:
        {
            if (SIMUL_RX == 0)
            {
                rx_temp = 0;
                rx_mask_cnt = 0;
                rx_time_out_cnt = 0;
                rx_tick_cnt = 0;
                g_e_simul_rx_stat = RX_START_BIT;
            }
        }
        break;
    case RX_START_BIT:
        {
            rx_tick_cnt++;
            if (rx_tick_cnt >= SIMUL_UART_ONE_TICK)
            {
                g_e_simul_rx_stat = RX_READ_8_BIT_DAT;
            }
            if (SIMUL_RX == 1)//开始帧结束,发生高电平变化
            {
                g_e_simul_rx_stat = RX_READ_8_BIT_DAT;
            }
        }
        break;
    case RX_READ_8_BIT_DAT:
        {
            rx_tick_cnt++;
            if (rx_tick_cnt >= SIMUL_UART_ONE_TICK || SIMUL_RX != last_pin_stat)
            {
                rx_tick_cnt = 0;
                last_pin_stat = SIMUL_RX;
                if (SIMUL_RX == 1)
                {
                    rx_temp |= (0x01 << rx_mask_cnt);
                }
                else if (SIMUL_RX == 0)
                {
                    /* code */
                }
                rx_mask_cnt+=1;
                if (rx_mask_cnt >= 8)
                {
                    rx_time_out_cnt = 0;
                    g_e_simul_rx_stat = RX_READ_END_BIT;
                }
            }
        }
        break;
    case RX_READ_END_BIT:
        {
            {
                rx_tick_cnt = 0;
                if (SIMUL_RX == 1)
                {
                    g_e_simul_rx_stat = RX_READ_1BYTE_SUCC;
                }
                else if (SIMUL_RX == 0)
                {
                    // g_e_simul_rx_stat = RX_READ_ERR;
                }
            }
            rx_time_out_cnt++;
            if (rx_time_out_cnt >= SIMUL_UART_RX_TIME_OUT_TICK)
            {
                rx_time_out_cnt = 0;
                g_e_simul_rx_stat = RX_READ_ERR;
            }
        }
        break;
    case RX_READ_1BYTE_SUCC:
        {
            Queue_Push(&q_simul_rx,rx_temp);
            g_e_simul_rx_stat = RX_IDLE;
        }
        break;
    case RX_READ_ERR:
        {
            g_e_simul_rx_stat = RX_IDLE;
        }
        break;
    default:
        g_e_simul_rx_stat = RX_IDLE;
        break;
    }
}
